﻿using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Kotonoha.Objects.Model;
using Kotonoha.Objects.Model.Event;
using Kotonoha.Objects.Selectors;
using Kotonoha.Client.Synch;
using Kotonoha.Server.Objects.Model;


namespace Kotonoha.Client.UI
{
    internal enum WordFormStates {
        ShowWriting = 0,
        ShowReading,
        ShowAll,
        Marked
    }

    [Flags]
    internal enum FormElements {
    }

    public partial class WordForm : Form
    {
        private Word word;
        private Button[] btns;
        public event Action ContainerChanged;
        private EventList events;
        private readonly Random r = new Random();
        private WordFormStates state;
        private Queue<Word> last = new Queue<Word>(50);
        private int examplePos;


        public Container Container { get; set; }

        public WordForm() {
            InitializeComponent();
            writingLabel.Font = new Font("Meiryo", 12, FontStyle.Regular);
            readingLabel.Font = new Font("Meiryo", 8, FontStyle.Regular);
            exampleLabel.Font = new Font("Meiryo", 8, FontStyle.Regular);
            btns = new[] {btn1, btn2, btn3, btn4, btn5};
            SynchronizationManager.SynchStart += SynchManager_SynchStart;
            events = new EventList(new FileInfo("./data/log").FullName);
        }

        private void SynchManager_SynchStart() {
            this.Invoke(new Action(this.Close));
        }

        private void setBtnsEnabled(bool b) {
            foreach (var btn in btns) {
                btn.Enabled = b;
            }
        }

        private void showLabels(bool b) {
            writingLabel.Visible = b;
            readingLabel.Visible = b;
            meaningLabel.Visible = b;
            exampleLabel.Visible = b;
        }

        private void nextBtn_Click(object sender, EventArgs e) {
            word = new SimpleWordSelector(Container).Selected;
            updateWord();
        }

        private void updateWord() {
            writingLabel.Text = word.Writing;
            readingLabel.Text = word.Reading;
            StringBuilder b = new StringBuilder();
            foreach (var c in word.Translations) {
                b.AppendLine(c);
            }

            updateExample(0);
            
            meaningLabel.Text = b.ToString();

            state = (WordFormStates) r.Next(2);
            updateState();
        }

        private void updateExample(int what) {
            int len = word.Examples.Length;
            if (len == 0) {
                exampleLabel.Text = "No examples";
                return;
            }

            if (what == 0) {
                examplePos = 0;
            } else {
                examplePos += what;
                if (examplePos < 0) {
                    examplePos = len - 1;
                } else if (examplePos >= len) {
                    examplePos = 0;
                }
            }

            Example e = word.Examples[examplePos];
            StringBuilder b = new StringBuilder(e.Translation.Length * 2);
            b.AppendFormat("({0}/{1})\n", examplePos + 1, len);
            b.AppendLine(e.Content);
            b.AppendLine(e.Translation);

            exampleLabel.Text = b.ToString();
        }

        private void WordForm_Load(object sender, EventArgs e) {
            nextBtn_Click(this, null);
        }

        private void knowBtn_Click(object sender, EventArgs e) {
            Button c = (Button) sender;
            string tag = (string) c.Tag;
            int val = int.Parse(tag);

            MarkEvent me = new MarkEvent {Mark = val, Time = DateTime.Now, WordId = word.Id};
            me.apply(word);
            events.save(me);
            
            if (ContainerChanged != null) {
                ContainerChanged.Invoke();
            }

            state = WordFormStates.Marked;
            updateState();
        }

        private void updateState() {
            switch (state) {
                case WordFormStates.Marked:
                    setBtnsEnabled(false);
                    break;
                case WordFormStates.ShowAll:
                    setBtnsEnabled(true);
                    showLabels(true);
                    break;
                case WordFormStates.ShowReading:
                    setBtnsEnabled(false);
                    showLabels(false);
                    readingLabel.Visible = true;
                    break;
                case WordFormStates.ShowWriting:
                    setBtnsEnabled(false);
                    showLabels(false);
                    writingLabel.Visible = true;
                    break;
            }
        }

        private void WordForm_KeyDown(object sender, KeyEventArgs e) {
            e.Handled = true;
        }

        private void WordForm_Closed(object sender, EventArgs e) {
            SynchronizationManager.SynchStart -= SynchManager_SynchStart;
        }

        private void WordForm_MouseDown(object sender, MouseEventArgs e) {
            Rectangle bnd = exampleLabel.Bounds;
            if (state == WordFormStates.ShowAll && bnd.Contains(e.X, e.Y)) {
                Rectangle left = new Rectangle(bnd.X, bnd.Y, bnd.Width / 2, bnd.Height);
                updateExample(left.Contains(e.X, e.Y) ? -1 : 1);
            } 
            if (state != WordFormStates.Marked) {
                state = WordFormStates.ShowAll;
                updateState();
            }
        }
    }
}